/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#ifndef OBS_COMMONSTRUCT_H
#define OBS_COMMONSTRUCT_H

#include <string>
#include <vector>
#include <set>
#include "Module/src/common/JsonHelper.h"
#include "manager/CloudServiceManager.h"
#include "common/CleanMemPwd.h"
#include "PrefixInfo.h"
namespace OBSPlugin {
const std::string DME_OBS_CONFIG_SECTION = "ObsPlugInConfig";
const std::string SHARED_RSC_GENEAL_INFO_KEY = "obs-geninfo-key";
const std::string OBS_GLOBAL_SCAN_REDO_LIST = "obs-global-scan-redo-list";
const std::string OBS_GLOBAL_STORAGE_STATUS_KEY = "obs-global-storage-status-key";
constexpr auto MODULECOM_OBS_COMMON = "ObjectStorageCommonService";
const std::string OBS_STORAGE_TYPE_PACIFIC = "1";

struct OBSBackupAdvParam {
    std::string m_multiNodeBackupSwitch; /* 多节点备份开关 true or false */
    std::string m_prefixSplitter;    /* 前缀拆分分隔符 */
    std::string m_prefixSplitDepth;          /* 前缀拆分层级 */
    std::string m_continueOnFailedSwitch;  /* 节点故障备份对象失败继续保护 true or false */
    std::string m_isBackupAcl;      /* 是否备份ACL */
    std::string m_useBucketLog;    /* 使用桶日志 */
    std::string m_aggregateSwitch;  /* 聚合开关 true or false */
    std::string m_maxSizeAfterAggregate; /* 对象聚合后的最大值，单位KB */
    std::string m_maxSizeToAggregate;    /* 被聚合对象的最大值，单位KB */
    std::string m_checkPoint;   /* 断点续传开关 */
    std::string m_retryNum;   /* 断点续传重试次数 */

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_multiNodeBackupSwitch, multiNodeBackupSwitch)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_prefixSplitter, prefixSplitter)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_prefixSplitDepth, prefixSplitDepth)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_continueOnFailedSwitch, continueOnFailedSwitch)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_isBackupAcl, isBackupAcl)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_useBucketLog, useBucketLog)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_aggregateSwitch, aggregateSwitch)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_maxSizeAfterAggregate, maxSizeAfterAggregate)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_maxSizeToAggregate, maxSizeToAggregate)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_checkPoint, checkPoint)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_retryNum, retryNum)
    END_SERIAL_MEMEBER
};

struct OBSProtectSubObject {
    std::string bucketName;       // 待保护的bucket名
    std::vector<std::string> prefixs; // 前缀过滤列表
    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(bucketName, name)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(prefixs, prefix)
    END_SERIAL_MEMEBER
};

struct ProtectedOBS {
    std::vector<OBSProtectSubObject> obsProtectSubObjectList; // 保护对象
    OBSBackupAdvParam advParms;   // 保护高级参数

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(obsProtectSubObjectList, bucketList)
    END_SERIAL_MEMEBER
};

struct ObjectStorageAuthExtendInfo {
    std::string storageType;
    std::string ak;
    std::string sk;
    std::string useHttps;
    std::string endPoint;
    std::string proxyEnable;
    std::string proxyHostName;
    std::string proxyUserName;
    std::string proxyUserPwd;
    std::string certification;

    Module::StorageType getStorageType() const
    {
        if (storageType.empty()) {
            return Module::StorageType::OTHER;
        }
        // 0 - other
        // 1 - pacific
        // 2 - hcs
        // 3 - ali
        return static_cast<Module::StorageType>(std::stoi(storageType));
    }

    bool openHttps() const
    {
        return useHttps == "1";
    }
    bool openProxy() const
    {
        return proxyEnable == "1";
    }

    ~ObjectStorageAuthExtendInfo()
    {
        Module::CleanMemoryPwd(sk);
        Module::CleanMemoryPwd(proxyUserPwd);
        Module::CleanMemoryPwd(certification);
    }
    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(storageType, storageType)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(ak, ak)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(sk, sk)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(useHttps, useHttps)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(endPoint, endpoint)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(proxyEnable, proxyEnable)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(proxyHostName, proxyHostName)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(proxyUserName, proxyUserName)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(proxyUserPwd, proxyUserPwd)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(certification, certification)
    END_SERIAL_MEMEBER
};

struct ObjectStorageBackupRecord {
    uint64_t m_lastBackupTime {};

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_lastBackupTime, lastBackupTime)
    END_SERIAL_MEMEBER
};

struct ObjectStorageBackupSubJob {
    uint32_t m_SubTaskType;  // 任务类型
    uint32_t orderNumberForAggregate {0};   // used in aggregate full restore. distinguishing the order of restore copy
    std::string copyId;      // 副本id;
    std::string esn;
    std::vector<PrefixInfo> prefixInfo; // 前缀扫描详细信息
    std::string m_ControlFile {};      // the control file while we receive in the call back of scanner/backupcopy phase
    std::string metaFilePath;
    std::string dcacheAndFcachePath;
    std::string dataCachePath;
    std::string checkpointCachePath;
    std::string m_Ext {};                 // any parameters required in future
    std::string storageAbnormal {"false"};

    // 将桶内多个前缀拆散，放在多个PrefixInfo中，以确保扫描时一次只扫描一个桶的一个前缀
    std::vector<PrefixInfo> GetFlatPrefixInfos() const
    {
        std::vector<PrefixInfo> splitPrefixInfos;
        for (const auto& originalInfo : prefixInfo) {
            // 多节点列举层级上的对象的目录不用做拆分，
            // 以及subPrefixs为空（未打开并行备份开关并且注册桶时没有设置前缀）时不用做拆分
            if (originalInfo.isPrefixLevelObject || originalInfo.subPrefixs.empty()) {
                splitPrefixInfos.emplace_back(originalInfo);
            } else {
                for (const auto& subPrefix : originalInfo.subPrefixs) {
                    auto newInfo = originalInfo;
                    newInfo.subPrefixs.clear();
                    newInfo.subPrefixs.emplace_back(subPrefix);
                    splitPrefixInfos.emplace_back(newInfo);
                }
            }
        }
        return splitPrefixInfos;
    }

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMEBER(copyId)
    SERIAL_MEMEBER(esn)
    SERIAL_MEMEBER(prefixInfo)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_SubTaskType, subTaskType)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(orderNumberForAggregate, orderNumberForAggregate)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_ControlFile, controlFile)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(metaFilePath, metaFilePath)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(dcacheAndFcachePath, dcacheAndFcachePath)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(dataCachePath, dataCachePath)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(checkpointCachePath, checkpointCachePath)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_Ext, Ext)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(storageAbnormal, storageAbnormal)

    END_SERIAL_MEMEBER
};

struct BackupObjectInfo {
    std::string esn;
    std::vector<PrefixInfo> prefixInfo;

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMEBER(esn)
    SERIAL_MEMEBER(prefixInfo)
    END_SERIAL_MEMEBER
};

struct FsRelation {
    std::string newEsn;
    std::string newFsId;
    std::string newFsName;
    std::string oldEsn;
    std::string oldFsId;
    std::string oldFsName;
    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMEBER(newEsn)
    SERIAL_MEMEBER(newFsId)
    SERIAL_MEMEBER(newFsName)
    SERIAL_MEMEBER(oldEsn)
    SERIAL_MEMEBER(oldFsId)
    SERIAL_MEMEBER(oldFsName)
    END_SERIAL_MEMEBER
};

struct FsRelationInCopy {
    std::vector<FsRelation> relations;
    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMEBER(relations)
    END_SERIAL_MEMEBER
};

struct BucketLogIncBackupInfo {
    // 只用于日志增量扫描
    std::vector<std::string> logBucketNames;
    std::vector<std::string> lastLogTimes; // 与m_logBucketName位置上一一匹配，记录了上一次备份所读取的最后一个日志生成时间

    void AddLastLogTime(const std::string& logBucketName, const std::string& lastLogTime)
    {
        logBucketNames.emplace_back(logBucketName);
        lastLogTimes.emplace_back(lastLogTime);
    }

    std::string GetLastLogTime(const std::string& logBucketName)
    {
        if (logBucketNames.size() != lastLogTimes.size()) {
            return "";
        }
        for (std::size_t i = 0; i < logBucketNames.size(); ++i) {
            if (logBucketNames[i] == logBucketName) {
                return lastLogTimes[i];
            }
        }
        return "";
    }

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMEBER(logBucketNames)
    SERIAL_MEMEBER(lastLogTimes)
    END_SERIAL_MEMEBER
};

struct BackupObjectInfosInCopy {
    std::vector<BackupObjectInfo> objectInfos;
    OBSBackupAdvParam advParms;   // 保护高级参数
    std::string pathSuffix;  // 备份存储子路径后缀（快照格式为空，目录格式为副本id）
    BucketLogIncBackupInfo bucketLogIncBackupInfo;
    FsRelationInCopy fsRelations;
    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMEBER(objectInfos)
    SERIAL_MEMEBER(advParms)
    SERIAL_MEMEBER(pathSuffix)
    SERIAL_MEMEBER(bucketLogIncBackupInfo)
    SERIAL_MEMEBER(fsRelations)
    END_SERIAL_MEMEBER
};

struct ObjectStorageNativeGeneral {
    time_t m_jobStartTime {};
    uint64_t m_backupCopyPhaseStartTime {};
    uint64_t m_backupDelPhaseStartTime {};
    uint32_t m_restoreCopyIndex {0};
    uint32_t m_restoreDeleteIndex {0};
    BucketLogIncBackupInfo bucketLogIncBackupInfo;

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_jobStartTime, JobStartTime)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_backupCopyPhaseStartTime, FirstBackupCopySubTaskStartTime)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_backupDelPhaseStartTime, FirstBackupCopyDelTaskStartTime)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_restoreCopyIndex, RestoreCopyIndex)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_restoreDeleteIndex, RestoreDeleteIndex)
    SERIAL_MEMEBER(bucketLogIncBackupInfo)
    END_SERIAL_MEMEBER
};

const std::string SHARED_RSC_SCANNER_STATS_KEY = "scan-stats-key";
struct ObjectStorageNativeScanStatistics {
    std::vector<PrefixInfo> m_scannedPrefixInfo;
    int m_scanStatus;                     /* Scan status (refer SCANNER_STATUS) */
    time_t m_scanStartTime = 0;           /* Scan start time */
    time_t m_remoteObsScanEndTime = 0;    /* Scan End time */
    time_t m_scanEndTime = 0;             /* Scan end time along with metadata write */
    uint64_t m_scanDuration = 0;          /* Total scan duration (in seconds) */
    uint64_t m_totDirs = 0;               /* Total num of dir detected in NAS Share */
    uint64_t m_totFiles = 0;              /* Total num of files detected in NAS Share */
    uint64_t m_totalSize = 0;             /* Total size of the NAS Share */
    uint64_t m_totDirsToBackup = 0;       /* Total num of dir (new/modified) to backup */
    uint64_t m_totFilesToBackup = 0;      /* Total num of files(new/modified) to backup */
    uint64_t m_totFilesDeleted = 0;       /* Total num of files to be deleted */
    uint64_t m_totDirsDeleted = 0;        /* Total num of dirs to be deleted */
    uint64_t m_totalSizeToBackup = 0;     /* Total size to backup */
    uint64_t m_totalControlFiles = 0;     /* Total Control Files Generated */
    uint64_t m_totFailedDirs = 0;         /* Total num of Failed dir detected in NAS Share */
    uint64_t m_totFailedFiles = 0;        /* Total num of Failed files detected in NAS Share */
    int64_t  m_lastLogReportTime  = 0;    /* Last time (epoch seconds) when we report log to PM */
    bool m_scanStarted = 0;

    bool FindScannedPrefixInfo(const PrefixInfo& prefixInfo) const
    {
        for (const auto& scannedPrefixInfo : m_scannedPrefixInfo) {
            if (prefixInfo.Equal(scannedPrefixInfo)) {
                return true;
            }
        }
        return false;
    }

    void ClearScannedPrefixInfo()
    {
        m_scannedPrefixInfo.clear();
    }

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_scannedPrefixInfo, scannedPrefixInfo)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_scanStatus, scanStatus)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_scanStartTime, scanStartTime)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_remoteObsScanEndTime, remoteObsScanEndTime)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_scanEndTime, scanEndTime)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_scanDuration, scanDuration)

    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totDirs, totDirs)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totFiles, totFiles)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totalSize, totalSize)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totDirsToBackup, totDirsToBackup)

    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totFilesToBackup, totFilesToBackup)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totFilesDeleted, totFilesDeleted)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totDirsDeleted, totDirsDeleted)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totalSizeToBackup, totalSizeToBackup)

    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totalControlFiles, m_totalControlFiles)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totFailedDirs, m_totFailedDirs)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_totFailedFiles, m_totFailedFiles)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_scanStarted, scanStarted)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_lastLogReportTime, lastLogReportTime)

    END_SERIAL_MEMEBER
};

const std::string SHARED_RSC_BACKUP_STATS_KEY  = "backup-stats-key";
struct ObjectStorageNativeBackupStats {
    uint32_t m_subJobPhrase       = 0;
    uint64_t m_noOfDirToBackup    = 0;        /* No of directories to be backed up */
    uint64_t m_noOfFilesToBackup  = 0;        /* No of files to be backed up */
    uint64_t m_noOfBytesToBackup  = 0;        /* No of bytes (in KB) to be backed up */
    uint64_t m_noOfDirToDelete    = 0;        /* No of directories to be deleted */
    uint64_t m_noOfFilesToDelete  = 0;        /* No of files to be deleted */
    uint64_t m_noOfDirCopied      = 0;        /* No of directories copied */
    uint64_t m_noOfFilesCopied    = 0;        /* No of files copied */
    uint64_t m_noOfBytesCopied    = 0;        /* No of bytes (in KB) copied */
    uint64_t m_noOfDirDeleted     = 0;        /* No of directories deleted */
    uint64_t m_noOfFilesDeleted   = 0;        /* No of files deleted */
    uint64_t m_noOfDirFailed      = 0;        /* No of directories failed to be copied/deleted */
    uint64_t m_noOfFilesFailed    = 0;        /* No of files failed to be copied/deleted */
    int64_t  m_lastLogReportTime  = 0;        /* Last time (epoch seconds) when we report log to PM */
    uint64_t m_noOfSrcRetryCount  = 0;        /* No of src side retry count */
    uint64_t m_noOfDstRetryCount  = 0;        /* No of dst retry count */
    uint64_t m_noOfFailureRecordsWritten = 0; /* No of backup failure records that have been written to file */
    time_t m_backupStartTime = 0;
    time_t m_backupEndTime = 0;

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_subJobPhrase, subJobPhrase)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfDirToBackup, noOfDirToBackup)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfFilesToBackup, noOfFilesToBackup)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfBytesToBackup, noOfBytesToBackup)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfDirToDelete, noOfDirToDelete)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfFilesToDelete, noOfFilesToDelete)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfDirCopied, noOfDirCopied)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfFilesCopied, noOfFilesCopied)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfBytesCopied, noOfBytesCopied)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfDirDeleted, noOfDirDeleted)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfFilesDeleted, noOfFilesDeleted)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfDirFailed, noOfDirFailed)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfFilesFailed, noOfFilesFailed)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_lastLogReportTime, lastLogReportTime)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfSrcRetryCount, noOfSrcRetryCount)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfDstRetryCount, noOfDstRetryCount)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_noOfFailureRecordsWritten, noOfFailureRecordsWritten)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_backupStartTime, backupStartTime)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_backupEndTime, backupEndTime)
    END_SERIAL_MEMEBER

    ObjectStorageNativeBackupStats& operator += (const ObjectStorageNativeBackupStats& subJobStats) {
        m_noOfDirToBackup    += subJobStats.m_noOfDirToBackup;
        m_noOfFilesToBackup  += subJobStats.m_noOfFilesToBackup;
        m_noOfBytesToBackup  += subJobStats.m_noOfBytesToBackup;
        m_noOfDirToDelete    += subJobStats.m_noOfDirToDelete;
        m_noOfFilesToDelete  += subJobStats.m_noOfFilesToDelete;
        m_noOfDirCopied      += subJobStats.m_noOfDirCopied;
        m_noOfFilesCopied    += subJobStats.m_noOfFilesCopied;
        m_noOfBytesCopied    += subJobStats.m_noOfBytesCopied;
        m_noOfDirDeleted     += subJobStats.m_noOfDirDeleted;
        m_noOfFilesDeleted   += subJobStats.m_noOfFilesDeleted;
        m_noOfDirFailed      += subJobStats.m_noOfDirFailed;
        m_noOfFilesFailed    += subJobStats.m_noOfFilesFailed;
        m_noOfSrcRetryCount  += subJobStats.m_noOfSrcRetryCount;
        m_noOfDstRetryCount  += subJobStats.m_noOfDstRetryCount;
        m_noOfFailureRecordsWritten  += subJobStats.m_noOfFailureRecordsWritten;
        return *this;
    }
};

struct ObjectStorageLastCopyDetails {
    std::string m_protocolVersion {};
    std::string m_metadataBackupType {};
    std::string m_backupFormat {};
    std::string m_backupFilter {};
    uint64_t m_lastBackupTime {};
    std::string m_oceanStorV5lastSnapshotName {};
    std::string m_isBackupAcl;
    std::string m_multiNodeBackupSwitch;
    std::vector<OBSProtectSubObject> m_obsProtectSubObjectList; // 保护对象
    std::string m_backupPath;

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_protocolVersion, protocolVersion)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_metadataBackupType, metadataBackupType)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_backupFormat, backupFormat)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_backupFilter, backupFilter)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_lastBackupTime, lastBackupTime)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_oceanStorV5lastSnapshotName, oceanStorV5lastSnapshotName)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_isBackupAcl, isBackupAcl)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_multiNodeBackupSwitch, multiNodeBackupSwitch)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_obsProtectSubObjectList, obsProtectSubObjectList)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(m_backupPath, backupPath)
    END_SERIAL_MEMEBER
};

struct ObjectStorageDataLayOutExtend {
    std::string fileReplaceStrategy {"0"};
    std::string bucketName;
    std::string prefix;
    std::string isNewCreateBucket;  // true:新建 false:不新建

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(fileReplaceStrategy, fileReplaceStrategy)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(bucketName, bucketName)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(prefix, prefix)
    SERIAL_MEMBER_TO_SPECIFIED_NAME(isNewCreateBucket, isNewCreateBucket)
    END_SERIAL_MEMEBER
};

struct ObjectStorageTargetEnvExtend {
    std::string storageType {"0"};

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(storageType, storageType)
    END_SERIAL_MEMEBER
};

enum class SCANNER_TASK_STATUS {
    SCANNER_TASK_STATUS_INIT        = 0,
    SCANNER_TASK_STATUS_INPROGRESS  = 1,
    SCANNER_TASK_STATUS_SUCCESS     = 2,
    SCANNER_TASK_STATUS_ABORTED     = 3,
    SCANNER_TASK_STATUS_FAILED      = 4,
};

struct StorageStatusInfo {
    std::string storageAbnormal {"false"};  // false: 正常, ture:异常;
    std::string esn;
    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMEBER(storageAbnormal)
    SERIAL_MEMEBER(esn)
    END_SERIAL_MEMEBER
};

struct StorageGeneralInfo {
    std::vector<StorageStatusInfo> storageStatus;
    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(storageStatus, storageStatus)
    END_SERIAL_MEMEBER
};

struct ObjectStorageCheckPointRecord {
    std::vector<std::string> errorCode;

    BEGIN_SERIAL_MEMEBER
    SERIAL_MEMBER_TO_SPECIFIED_NAME(errorCode, errorCode)
    END_SERIAL_MEMEBER
};

}
#endif